<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .wrap {
            padding: 10px;
        }

        .button-group button {
            padding: 2px 5px;
        }

        .button-group button+button {
            margin-left: 10px;
        }

        .slideBar {
            width: 1100px;
            height: 100px;
            margin-top: 20px;
            border: 1px solid #333;
            border-top: 0;
            position: relative;
            /* transition: all 0.5s ease-out; */

        }

        .slideBar:hover {
            width: 1100px;

        }

        .slideBar .ball {
            width: 100px;
            height: 100px;
            background-color: #6ff;
            /* border-radius: 50%; */
            position: absolute;
            left: 0px;
            top: 0;

        }
    </style>
</head>

<body>
    <!-- .wrap>.button-group>button.start{开始}+button.pause{暂停}+button.back{返回} -->
    <div class="wrap">
        <div class="button-group">
            <button class="start">开始</button>
            <button class="pause">暂停</button>
            <button class="back">返回</button>
        </div>
        <div class="slideBar">
            <div class="ball"></div>
        </div>
    </div>
</body>
<script>
    // JS运动 => 每隔一段时间操作元素运动(运动的属性 left  top width height opacity等相关属性的变化)

    // 1.  每隔一段时间 => 计时器/延时器
    // 2.  操作元素运动 => 改变元素的位置 宽高 opacity

    var start = document.getElementsByClassName("start")[0];
    var pause = document.getElementsByClassName("pause")[0];
    var back = document.getElementsByClassName("back")[0];

    var ball = document.getElementsByClassName("ball")[0];

    var timer = null;

    // 正向运动: (终点值 > 起点值)   当前位置 -> 1000
    start.onclick = function () {
        // animate(ball, "left", 1000,"ease-in",function(){
        //     console.log("到达终点,left:1000");
        //     animate(ball, "top", 500,"ease-in",function(){
        //         console.log("到达终点,top:500");
        //     });
        // });


        animate(ball, "left", 1000, "ease-in", function () {
            console.log("到达终点,left:1000");
            animate(ball, "top", 500, "ease-in", function () {
                console.log("到达终点,top:500");
                animate(ball, "left", 0, "ease-out", function () {
                    console.log("到达终点,left:0");
                    animate(ball, "top", 0, "ease-out", function () {
                        console.log("到达终点,top:0");
                    });
                });
            });
        });

    }

    pause.onclick = function () {
        clearInterval(timer);
    }



    // 反向运动: (终点值 < 起点值)   当前位置 -> 1000
    back.onclick = function () {
        animate(ball, "left", 0, "ease-out");
    }


    // 新增功能 -> 链式运动 -> 在上次运动接收之后,可以执行特定内容 (判断运动结束,或开启下一次运动)

    // ele    => 运动的元素
    // cssKey => 运动的css属性
    // end    => 终点 (如果有单位px => 去单位)
    // aniType => 运动的方式 (linear  ease-in  ease-out  )
    // callback  => 运动结束时执行的回调函数
    function animate(ele, cssKey, end, aniType = "linear", callback) {
        // cur => 局部变量   =>  a. 记录小球的当前位置(初始位置)  b. 每隔固定时间之后移动的位置 

        // var cur = ele.offsetTop;  // offsetTop offsetLeft clientWidth clientHeight =>快捷取值
        // var cur = getVal(ele,"top");

        var cur = getVal(ele, cssKey);

        end = parseFloat(end); // (如果有单位px => 去单位)


        var speed = 0;


        // 为了防止每次点击 都启动新的计时器 => 开启下一次之前,先清除上一个 => 保证只有一个计时器
        clearInterval(timer);
        timer = setInterval(() => {

            if (aniType == "linear") { //   // 匀速运动

                if (end > cur) {  // 正向运动
                    speed = 10;
                } else if (end < cur) { // 反向运动
                    speed = -10;
                } else { // end == cur 
                    speed = 0;  // end == cur  已经在终点 => 跑个鬼
                }

            } else if (aniType == "ease-in") { // 加速运动
                if (end > cur) {  // 正向运动
                    speed += 2;
                } else if (end < cur) { // 反向运动
                    speed -= 2;
                } else { // end == cur 
                    speed = 0;  // end == cur  已经在终点 => 跑个鬼
                }
            } else if (aniType == "ease-out") {
                // 缓冲运动
                // 每天走剩余 n / 1  =>  (终点值 - 当前值) / n   => n就是缓冲因子
                // 缓冲因子 一般设置为8-12

                // 缺点:  每天走剩余 n / 1 => 永远到不了终点  => 可以在 |speed| < 1 是 走1像素 

                // 缓冲运动
                if (end > cur) {  // 正向运动
                    speed = (end - cur) / 10;
                    speed = Math.ceil(speed);  // 0.1 向上取值 1
                } else if (end < cur) { // 反向运动
                    speed = (end - cur) / 10;
                    speed = Math.floor(speed);  // -0.1 > -1 => 向下取值才能=>-1
                } else { // end == cur 
                    speed = 0;  // end == cur  已经在终点 => 跑个鬼
                }
            }

            // console.log(speed);

            cur += speed;  // 相对于当前位置移动
            ele.style[cssKey] = cur + "px";

            if (Math.abs(end - cur) <= Math.abs(speed)) { // 临界值判断 -> 运动到达终点
                clearInterval(timer);
                ele.style[cssKey] = end + "px";

                if (callback && typeof callback == "function") { //  到达终点值 执行传入的回调函数
                    callback();
                }

            }

        }, 10);

    }

    function getStyle(ele, cssKey) {
        return window.getComputedStyle(ele)[cssKey];
    }

    function getVal(ele, cssKey) {
        return parseFloat(getStyle(ele, cssKey));
    }



</script>

</html>